using System;
using Cysharp.Threading.Tasks;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;

/// <summary>
/// 人像分割
/// </summary>
public static class BodySegUtil 
{
    // 你的 API Key 和 Secret Key （在百度智能云控制台获取）
    private static  readonly string apiKey = "snPWcCMLgEgss74SXeYUHaWE"; // client_id
    private static  readonly  string secretKey = "4BvZ2XOXRVXn5ahOua2jNIWYY9tOipn2"; // client_secret
    // 存储 Access Token
    public static string accessToken = "24.21601974ec836240e649462f26723dff.2592000.1764210476.282335-120540948";

    /// <summary>
    /// 请求Access Token,一个Token能使用一个月
    /// </summary>
    /// <returns></returns>
    public static async UniTask<string> GetAccessToken()
    {
        string url = $"https://aip.baidubce.com/oauth/2.0/token?" +
                     $"grant_type=client_credentials&client_id={apiKey}&client_secret={secretKey}";

        using (UnityWebRequest www = UnityWebRequest.PostWwwForm(url, ""))
        {
            www.downloadHandler = new DownloadHandlerBuffer();
            await www.SendWebRequest();

            if (www.result != UnityWebRequest.Result.Success)
            {
                Debug.LogError("获取 Access Token 失败: " + www.error);
            }
            else
            {
                string json = www.downloadHandler.text;
                Debug.Log("返回结果: " + json);

                // 从返回 JSON 中解析 access_token
                TokenResponse token = JsonUtility.FromJson<TokenResponse>(json);
                accessToken = token.access_token;
                Debug.Log("Access Token: " + accessToken);
            }

            return accessToken;
        }
    }

    public static async UniTask<Texture2D> BodySegCoroutine(Texture2D sourceTexture)
    {
        // 将 Texture2D 转 Base64
        byte[] bytes = sourceTexture.EncodeToJPG();
        string base64 = Convert.ToBase64String(bytes);

        // 请求 URL
        string url = $"https://aip.baidubce.com/rest/2.0/image-classify/v1/body_seg?access_token={accessToken}";

        // 构造表单
        WWWForm form = new WWWForm();
        form.AddField("image", base64);
        form.AddField("type", "foreground"); // 返回透明背景图

        using (UnityWebRequest www = UnityWebRequest.Post(url, form))
        {
            www.downloadHandler = new DownloadHandlerBuffer();
            await www.SendWebRequest();

            if (www.result != UnityWebRequest.Result.Success)
            {
                Debug.LogError("调用人像分割接口失败：" + www.error);
            }
            
            string errorJson = www.downloadHandler.text;
            Debug.Log($"接口返回：{errorJson}");
            
            //这里进行一次过期Token的验证逻辑    
            if (errorJson.Contains("error_code"))
            {
                var error = JsonUtility.FromJson<BaiduErrorResponse>(errorJson);
                Debug.LogWarning($"调用失败：{error.error_code} - {error.error_msg}");

                if (error.error_code == 110 || error.error_code == 111)
                {
                    // token 无效或过期就再次获取token，然后重试一次
                    accessToken = await GetAccessToken();
                    return await BodySegCoroutine(sourceTexture); 
                }
                else
                {
                    // 其他错误直接返回
                    return null;
                }
            }
            else          
            {
                string json = www.downloadHandler.text;
                Debug.Log("返回结果：" + json);

                // 解析 JSON
                BodySegResponse response = JsonUtility.FromJson<BodySegResponse>(json);

                if (!string.IsNullOrEmpty(response.foreground))
                {
                    byte[] imgData = Convert.FromBase64String(response.foreground);
                    Texture2D resultTex = new Texture2D(2, 2, TextureFormat.RGBA32, false);
                    resultTex.LoadImage(imgData);
                    return resultTex;
                }
                else
                {
                    Debug.LogWarning("未获得 foreground 数据");
                }
            }
            return null;
        }
    }

    [Serializable]
    public class BodySegResponse
    {
        public string foreground;
    }
    [Serializable]
    public class BaiduErrorResponse
    {
        public int error_code;
        public string error_msg;
    }
    [Serializable]
    public class TokenResponse
    {
        public string access_token;
        public int expires_in;
        public string scope;
    }
}
